using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using mb;

namespace libmp
{

    // public static class Http
    // {
    //     public class Option
    //     {
    //         public string Url;
    //         public HttpMethod Method;
    //         public string Body;
    //         public int TimeoutSec;
    //         public Action<long, long> OnProgress;
    //         public Action<bool, int, string> OnFinish;
    //         public string SaveAs;

    //         public Option()
    //         {
    //             Method = HttpMethod.Get;
    //             TimeoutSec = 0;
    //         }
    //     }

    //     static HttpClient httpClient;
    //     static ILog logger = mb.ServiceLocator.Instance.Get<ILog>();

    //     static Http()
    //     {
    //         httpClient = new HttpClient();
    //     }

    //     public async static Task < (int, string) > MakeRequest(Option opt)
    //     {
    //         var request = new HttpRequestMessage
    //         {
    //             RequestUri = new System.Uri(opt.Url),
    //             Method = opt.Method,
    //         };

    //         try
    //         {
    //             if (opt.TimeoutSec > 0)
    //                 httpClient.Timeout = TimeSpan.FromSeconds(opt.TimeoutSec);

    //             if (opt.Body != null)
    //             {
    //                 logger.Log("http body", opt.Body);
    //                 request.Content = new StringContent(opt.Body);
    //             }

    //             var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
    //             // response.EnsureSuccessStatusCode();

    //             string result = null;
    //             var totalBytes = response.Content.Headers.ContentLength;
    //             using(var contentStream = await response.Content.ReadAsStreamAsync())
    //             {
    //                 logger.Log("http read stream", totalBytes, response.StatusCode);

    //                 var totalBytesRead = 0L;
    //                 var readCount = 0L;
    //                 var buffer = new byte[16 * 1024];
    //                 var isMoreToRead = true;

    //                 FileStream fileStream = null;
    //                 MemoryStream memStream = null;
    //                 if (opt.SaveAs != null)
    //                     fileStream = new FileStream(opt.SaveAs, FileMode.Create, FileAccess.Write, FileShare.None, buffer.Length, true);
    //                 else
    //                     memStream = new MemoryStream();

    //                 do
    //                 {
    //                     var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
    //                     if (bytesRead == 0)
    //                     {
    //                         isMoreToRead = false;
    //                         opt.OnProgress?.Invoke((long) totalBytes, (long) totalBytes);
    //                         break;
    //                     }

    //                     if (fileStream != null)
    //                         fileStream.WriteAsync(buffer, 0, bytesRead);
    //                     else
    //                         memStream.WriteAsync(buffer, 0, bytesRead);

    //                     totalBytesRead += bytesRead;
    //                     readCount += 1;

    //                     opt.OnProgress?.Invoke((long) totalBytes, (long) totalBytes);
    //                 }
    //                 while (isMoreToRead);

    //                 if (fileStream != null)
    //                 {
    //                     fileStream.Close();
    //                 }
    //                 else
    //                 {
    //                     result = Encoding.UTF8.GetString(memStream.ToArray());
    //                 }
    //             }

    //             opt.OnFinish?.Invoke(true, (int) response.StatusCode, result);
    //             return ((int) response.StatusCode, result);
    //         }
    //         catch (System.Exception e)
    //         {
    //             opt.OnFinish?.Invoke(false, 0, e.ToString());
    //             return (0, e.ToString());
    //         }

    //     }

    // }
}